package cn.iocoder.yudao.module.contract.controller.admin.orderContract;

import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.module.contract.dal.dataobject.client.ClientDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.frameworkAgreement.FrameworkAgreementDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.contract.service.client.ClientService;
import cn.iocoder.yudao.module.contract.service.frameworkAgreement.FrameworkAgreementService;
import cn.iocoder.yudao.module.contract.service.order.OrderService;
import cn.iocoder.yudao.module.contract.utils.FileDownloadUtil;
import cn.iocoder.yudao.module.contract.utils.StringUtils;
import cn.iocoder.yudao.module.contract.webservice.ContractWebService;
import cn.iocoder.yudao.module.contract.webservice.holders.TABLE_OF_ZJS004HHolder;
import cn.iocoder.yudao.module.contract.webservice.holders.TABLE_OF_ZJS004IHolder;
import cn.iocoder.yudao.module.contract.webservice.ZJS004H;
import cn.iocoder.yudao.module.contract.webservice.ZJS004I;
import cn.iocoder.yudao.module.contract.webservice.ZWB_JS_BindingStub;
import cn.iocoder.yudao.module.contract.webservice.ZWB_JS_ServiceLocator;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.annotation.security.PermitAll;
import javax.validation.*;
import javax.servlet.http.*;
import javax.xml.namespace.QName;
//import javax.xml.ws.BindingProvider;
//import javax.xml.ws.Holder;
//import javax.xml.ws.Service;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.rmi.RemoteException;
import java.time.LocalDateTime;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.contract.controller.admin.orderContract.vo.*;
import cn.iocoder.yudao.module.contract.dal.dataobject.orderContract.OrderContractDO;
import cn.iocoder.yudao.module.contract.service.orderContract.OrderContractService;

@Tag(name = "管理后台 - 订单合同")
@RestController
@RequestMapping("/contract/order-contract")
@Validated
@Slf4j
public class OrderContractController {

    @Resource
    private OrderContractService orderContractService;
    @Resource
    private OrderService orderService;
    @Resource
    private ContractWebService contractWebService;
    @Resource
    private FrameworkAgreementService frameworkAgreementService;
    @Resource
    private ClientService clientService;

//    @PostMapping("/create")
//    @Operation(summary = "创建订单合同")
//    @PreAuthorize("@ss.hasPermission('contract:order-contract:create')")
//    public CommonResult<Long> createOrderContract(@Valid @RequestBody OrderContractSaveReqVO createReqVO) {
//        return success(orderContractService.createOrderContract(createReqVO));
//    }

    @PutMapping("/update")
    @Operation(summary = "更新订单合同")
    @PreAuthorize("@ss.hasPermission('contract:order-contract:update')")
    public CommonResult<Boolean> updateOrderContract(@Valid @RequestBody OrderContractSaveReqVO updateReqVO) {
        orderContractService.updateOrderContract(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除订单合同")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('contract:order-contract:delete')")
    public CommonResult<Boolean> deleteOrderContract(@RequestParam("id") Long id) {
        orderContractService.deleteOrderContract(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得订单合同")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('contract:order-contract:query')")
    public CommonResult<OrderContractRespVO> getOrderContract(@RequestParam("id") Long id) {
        OrderContractDO orderContract = orderContractService.getOrderContract(id);
        return success(BeanUtils.toBean(orderContract, OrderContractRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得订单合同分页")
    @PreAuthorize("@ss.hasPermission('contract:order-contract:query')")
    public CommonResult<PageResult<OrderContractPageRespVO>> getOrderContractPage(@Valid OrderContractPageReqVO pageReqVO) {
        PageResult<OrderContractPageRespVO> pageResult = orderContractService.getOrderContractPage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出订单合同 Excel")
    @PreAuthorize("@ss.hasPermission('contract:order-contract:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportOrderContractExcel(@Valid OrderContractPageReqVO pageReqVO,
                                         HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<OrderContractPageRespVO> list = orderContractService.getOrderContractPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "订单合同" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xls", "数据", OrderContractExportVO.class,
                BeanUtils.toBean(list, OrderContractExportVO.class));
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/download")
    public ResponseEntity<?> download(String ids) throws UnsupportedEncodingException {
        String[] id = ids.split(",");
        if (id.length == 1) {
            //单文件下载
            OrderContractDO orderContract = orderContractService.getById(id[0]);
            orderContract.setDownloadCount(orderContract.getDownloadCount() + 1);
            orderContractService.updateById(orderContract);
            OrderDO orderDO = orderService.getOrder(orderContract.getOrderId());
            //orderDO.getVbeln()+orderDO.getKname()+orderDO.getVkorg()+orderDO.getYwyt()
            String fileNmae = orderDO.getKname() + orderDO.getVbeln() + orderDO.getYwyt() + orderDO.getVkorg();
            if ("Y3".equals(orderDO.getHtdymb())) {
                fileNmae = orderDO.getYwyt() + orderDO.getKname() + orderDO.getVbeln() + orderDO.getBukrs();
            }
            return FileDownloadUtil.downloadFile(orderContract.getContractFileUrl(), URLEncoder.encode(fileNmae, "UTF-8"));
        } else if (id.length > 1) {
            //批量下载
            List<OrderContractDO> list = orderContractService.list(Wrappers.<OrderContractDO>lambdaQuery().in(OrderContractDO::getId, id));
            List<String> fileUrls = new ArrayList<>();
            List<String> fileNames = new ArrayList<>();
            for (OrderContractDO orderContract : list) {
                OrderDO orderDO = orderService.getOrder(orderContract.getOrderId());
                fileUrls.add(orderContract.getContractFileUrl());
                String fileNmae = orderDO.getKname() + orderDO.getVbeln() + orderDO.getYwyt() + orderDO.getVkorg();
                if ("Y3".equals(orderDO.getHtdymb())) {
                    //业务员名称+客户名称+销售订单号+公司主体编号；
                    fileNmae = orderDO.getYwyt() + orderDO.getKname() + orderDO.getVbeln() + orderDO.getBukrs();
                }
                fileNames.add(fileNmae);
//                fileNames.add(orderDO.getVbeln()+orderDO.getKname()+orderDO.getVkorg()+orderDO.getYwyt());
            }
            orderContractService.update(Wrappers.<OrderContractDO>update().setSql(" download_count = download_count + 1").in("id", id));
            return FileDownloadUtil.downloadZip(fileUrls, fileNames);
        } else {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "请选择要下载的合同");

        }
    }

    /**
     * 合同打印计数
     */
    @GetMapping("/prints")
    public CommonResult<?> prints(String ids) {
        String[] id = ids.split(",");
        if (id.length != 0) {
            orderContractService.update(Wrappers.<OrderContractDO>update().setSql(" print_count = print_count + 1").in("id", id));
            return success("操作成功");
        } else {
            return CommonResult.error(NOT_IMPLEMENTED);
        }
    }

    @PutMapping("/fileUpload")
    @Operation(summary = "合同上传")
    public CommonResult<Boolean> fileUpload(@Valid @RequestBody OrderContractSaveReqVO updateReqVO) {
//        if (StringUtils.isBlank(updateReqVO.getFileIds()) && StringUtils.isBlank(updateReqVO.getScanFileIds()) ) {
//            return error("请上传文件");
//        }
        OrderContractDO orderContract = orderContractService.getById(updateReqVO.getId());
        OrderDO orderDO = orderService.getOrder(orderContract.getOrderId());
        if (orderDO == null) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "订单不存在");
        }

        OrderContractDO updateObj = BeanUtils.toBean(updateReqVO, OrderContractDO.class);
        if(orderContract.getFileUploadTime()==null && StringUtils.isNotBlank(updateObj.getFileIds())){
            updateObj.setFileUploadTime(LocalDateTime.now());
        }
        if(orderContract.getScanFileUploadTime()==null && StringUtils.isNotBlank(updateObj.getScanFileIds())){
            updateObj.setScanFileUploadTime(LocalDateTime.now());
        }
        orderContractService.updateById(updateObj);
//        orderContractService.fileUpload(updateReqVO);
//        orderContract.setFileIds(updateReqVO.getFileIds());
        if (StringUtils.isNotBlank(updateReqVO.getFileIds()) || StringUtils.isNotBlank(updateReqVO.getScanFileIds())) {
            if (!"4".equals(orderContract.getOrderStatus())) {
                updateObj.setOrderStatus("4");
                contractWebService.pushOrderStatus(orderDO.getVbeln(), "4", updateObj);
                orderContractService.updateById(updateObj);
            }
        }
//        updateObj.setStatus("2");
        String scanFileIds = updateReqVO.getScanFileIds();
        if(StringUtils.isNotEmpty(scanFileIds)){
            orderContract = orderContractService.getById(updateReqVO.getId());
            //释放合同冻结
            boolean success =contractWebService.pushContractRelease(orderDO.getVbeln(), orderContract);
            orderContractService.updateById(orderContract);
            if (success) {
                orderContractService.orderContractRelease(updateReqVO.getId());
            }
//        else {
//            return error(orderContract.getAbnormalCause());
//        }
        }

        return success(true);
    }

    @GetMapping("/pushRelease")
    @Operation(summary = "推送释放")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> pushRelease(@RequestParam("id") Long id) {
        OrderContractDO orderContract = orderContractService.getOrderContract(id);
        OrderDO orderDO = orderService.getOrder(orderContract.getOrderId());
        if (orderDO == null) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "订单不存在");
        }
        contractWebService.pushOrderStatus(orderDO.getVbeln(), orderContract.getOrderStatus(), orderContract);
        orderContractService.updateById(orderContract);
        if ("1".equals(orderContract.getIsPushRelease())) {
            return success(true);
        } else {
            return error(orderContract.getAbnormalCause());
        }

    }

    @GetMapping("/cancellation")
    @Operation(summary = "作废")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> cancellation(@RequestParam("id") Long id) {
        OrderContractDO orderContract = orderContractService.getOrderContract(id);
        OrderDO orderDO = orderService.getOrder(orderContract.getOrderId());
        if (orderDO == null) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "订单不存在");
        }
        orderContract.setOrderStatus("3");
        orderContract.setStatus("0");
        orderContract.setContractHtml("");
        orderContract.setContractFileUrl("");
        orderContractService.updateById(orderContract);
        contractWebService.pushOrderStatus(orderDO.getVbeln(), "3", orderContract);
        orderContractService.updateById(orderContract);

        OrderDO order = new OrderDO();
        order.setId(orderDO.getId());
        order.setContractId("");
        order.setContractNo("");
        order.setStatus("0");
        orderService.updateById(order);

        if ("1".equals(orderContract.getIsPushRelease())) {
            return success(true);
        } else {
            return error(orderContract.getAbnormalCause());
        }

    }

    @GetMapping("/generateContractFile")
    @Operation(summary = "合同生成")

    public CommonResult<Boolean> generateContractFile(String id) {
        OrderContractDO orderContrac = orderContractService.getById(id);
        if (orderContrac == null) {
            return error("合同不存在");
        }
        orderContractService.generateContractFile(orderContrac);
        if ("1".equals(orderContrac.getStatus()) && !"2".equals(orderContrac.getOrderStatus())) {
            OrderDO orderDO = orderService.getById(orderContrac.getOrderId());
            orderContrac.setOrderStatus("2");
            contractWebService.pushOrderStatus(orderDO.getVbeln(), "2", orderContrac);
        }
        orderContractService.updateById(orderContrac);
        if (!"1".equals(orderContrac.getStatus())) {
            return error(orderContrac.getAbnormalCause());
        }
        return success(true);
    }


    @PostMapping("/api/invalid")
    @Operation(summary = "作废")
    @PermitAll
    public CommonResult<?> invalid(@RequestBody Map<String, String> param) {
        String vbelns = param.get("vbelns");
        if (StringUtils.isBlank(vbelns)) {
            return error("销售凭证不能为空");
        }
        List<String> vbelnList = Arrays.asList(vbelns.split(","));
        List<OrderContractDO> updateList = new ArrayList<>();
        for (String vbeln : vbelnList) {
            OrderDO orderDO = orderService.getOne(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getVbeln, vbeln), false);
            if (orderDO == null) {
                return error("未找到销售凭证-" + vbeln + "的订单数据");
            }
            OrderContractDO orderContract = orderContractService.getOne(new LambdaQueryWrapper<OrderContractDO>().eq(OrderContractDO::getOrderId, orderDO.getId()), false);
            if (orderContract == null) {
                return error("未找到销售凭证-" + vbeln + "的合同数据");
            }
            updateList.add(orderContract);
        }
        for (OrderContractDO orderContract : updateList) {
            OrderDO orderDO = orderService.getById(orderContract.getOrderId());
            orderContract.setOrderStatus("3");
            orderContract.setStatus("0");
            orderContract.setContractHtml("");
            orderContract.setContractFileUrl("");
            orderContractService.updateById(orderContract);
            contractWebService.pushOrderStatus(orderDO.getVbeln(), "3", orderContract);
            orderContractService.updateById(orderContract);
        }
        return success(null);
    }

    @PostMapping("/api/updateStatus")
    @Operation(summary = "更新状态")
    @PermitAll
    public CommonResult<?> updateStatus(@RequestBody Map<String, String> param) {
        String vbelns = param.get("vbelns");
        if (StringUtils.isBlank(vbelns)) {
            return error("销售凭证不能为空");
        }
        String status = param.get("status");
        if (StringUtils.isBlank(status)) {
            return error("状态不能为空");
        }
        List<String> vbelnList = Arrays.asList(vbelns.split(","));
        List<OrderContractDO> updateList = new ArrayList<>();
        for (String vbeln : vbelnList) {
            OrderDO orderDO = orderService.getOne(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getVbeln, vbeln), false);
            if (orderDO == null) {
                return error("未找到销售凭证-" + vbeln + "的订单数据");
            }
            OrderContractDO orderContract = orderContractService.getOne(new LambdaQueryWrapper<OrderContractDO>().eq(OrderContractDO::getOrderId, orderDO.getId()), false);
            if (orderContract == null) {
                return error("未找到销售凭证-" + vbeln + "的合同数据");
            }
            updateList.add(orderContract);
        }
        for (OrderContractDO orderContract : updateList) {
            OrderDO orderDO = orderService.getById(orderContract.getOrderId());
            switch (status) {
                case "0":
                case "1":
                case "4":
                    orderContract.setOrderStatus(status);
                    contractWebService.pushOrderStatus(orderDO.getVbeln(), "2", orderContract);
                    orderContractService.updateById(orderContract);
                    break;
                case "2":
                    orderContractService.generateContractFile(orderContract);
                    if ("1".equals(orderContract.getStatus()) && !"2".equals(orderContract.getOrderStatus())) {
                        orderContract.setOrderStatus("2");
                        contractWebService.pushOrderStatus(orderDO.getVbeln(), "2", orderContract);
                    }
                    orderContractService.updateById(orderContract);
                    break;
                case "3":
                    orderContract.setOrderStatus("3");
                    orderContract.setStatus("0");
                    orderContract.setContractHtml("");
                    orderContract.setContractFileUrl("");
                    orderContractService.updateById(orderContract);
                    contractWebService.pushOrderStatus(orderDO.getVbeln(), "3", orderContract);
                    orderContractService.updateById(orderContract);
                    break;
                default:
                    return error("状态值非法");
            }
        }
        return success(null);
    }

    @GetMapping("/testGetOrder")
    @Operation(summary = "测试获取订单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> getOrderContract(@RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate) {
//        ,@RequestParam(value = "vbeln",required = false) String vbeln
        contractWebService.getOrderList("");
        return success(true);
    }

    @GetMapping("/testGetClinet")
    @Operation(summary = "测试获取客户")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> testGetClinet(@RequestParam("endDate") String endDate) {
//        ,@RequestParam(value = "vbeln",required = false) String vbeln
        contractWebService.getClient(endDate, "");
        return success(true);
    }

    @GetMapping("/test")
    @PermitAll
    public CommonResult<?> test() {
        List<OrderContractDO> list = orderContractService.list(new LambdaQueryWrapper<OrderContractDO>().eq(OrderContractDO::getContractTypeCode, "Y3").eq(OrderContractDO::getStatus, "1").isNull(OrderContractDO::getFrameworkAgreementId));
        for (OrderContractDO orderContractDO : list) {
            OrderDO orderDO = orderService.getById(orderContractDO.getOrderId());
            ClientDO clientDO = clientService.getOne(Wrappers.<ClientDO>lambdaQuery().eq(ClientDO::getClientCode, orderDO.getKunnr()), false);

            if (clientDO != null) {
                if (orderContractDO.getContractTypeCode().equals("Y3")) {
                    FrameworkAgreementDO frameworkAgreementDO = frameworkAgreementService.getOne(Wrappers.<FrameworkAgreementDO>lambdaQuery()
                            .eq(FrameworkAgreementDO::getClientName, clientDO.getClientName())
                            .ge(FrameworkAgreementDO::getAgreementEndDate, orderDO.getAudat())
                            .le(FrameworkAgreementDO::getAgreementStartDate, orderDO.getAudat()), false);
                    if (frameworkAgreementDO != null) {

                        OrderContractDO contractDO = new OrderContractDO();
                        contractDO.setId(orderContractDO.getId());
                        contractDO.setFrameworkAgreementId(frameworkAgreementDO.getId());
                        orderContractService.updateById(contractDO);
                    } else {
                        throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), orderContractDO.getId() + "当前报价单未找到框架协议");
                    }
                }
            }
        }

        return success(true);
    }

    @PostMapping("/freeze")
    @Operation(summary = "冻结合同")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> orderContractFreeze(@RequestParam("id") Long id) {
        OrderContractDO orderContract = orderContractService.getOrderContract(id);
        OrderDO orderDO = orderService.getOrder(orderContract.getOrderId());
        if (orderDO == null) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "订单不存在");
        }
        boolean success = contractWebService.pushContractFreeze(orderDO.getVbeln(), orderContract);
        orderContractService.updateById(orderContract);
        if (success) {
            boolean result = orderContractService.orderContractFreeze(id);
            return result ? success("冻结成功") : error("冻结失败");
        } else {
            return error(orderContract.getAbnormalCause());
        }
    }

    @PostMapping("/release")
    @Operation(summary = "释放冻结合同")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<?> orderContractRelease(@RequestParam("id") Long id) {
        OrderContractDO orderContract = orderContractService.getOrderContract(id);
        OrderDO orderDO = orderService.getOrder(orderContract.getOrderId());
        if (orderDO == null) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "订单不存在");
        }
        boolean success = contractWebService.pushContractRelease(orderDO.getVbeln(), orderContract);
        orderContractService.updateById(orderContract);
        if (success) {
            boolean result = orderContractService.orderContractRelease(id);
            return result ? success("冻结释放成功") : error("冻结释放失败");
        } else {
            return error(orderContract.getAbnormalCause());
        }
    }
}